// -*- coding: utf-8 -*- 

import com.sun.xml.internal.ws.util.CompletedFuture;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**
 * Project: Java8InActionT
 * Creator: yanking
 * Create time: 2022-01-14 15:09
 * IDE: IntelliJ IDEA
 * Introduction:
 */

public class test {
    public static int portNumber = 2032;
    public int tmp = 1234;
    BiPredicate<List<String>, String> contains = List::contains;

    public void setTmp(int tmp) {
        this.tmp = tmp;
    }

    public void setPortNumber(int portNumber) {
        this.portNumber = portNumber;
    }

    @Test
    public void shout() {
        int a = 8;
        Runnable r = () -> {
            System.out.println(a);
        };
        r.run();
    }

    @Test
    public void shout01() {
        System.out.println("Before" + portNumber);
        Runnable r = () -> this.setPortNumber(123);
        r.run();
        // Runnable r = () -> portNumber = 566; Lambda表达式的不能修改参数的值，只允许进行访问
        System.out.println("After" + portNumber);

    }

    public boolean isEven(Predicate<Integer> isEven, Integer num) {
        if (isEven.test(num)) {
            return true;
        } else {
            return false;
        }
    }

    @Test
    public void shout18() {
        List<Integer> list = IntStream.rangeClosed(0, 100).boxed().collect(toList());
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()) {
            Integer next = iterator.next();
            if (isEven(a -> a % 2 == 0, next)) {
                System.out.print(next + "\t");
            } else {
                iterator.remove();
            }
        }
        System.out.print("\nlist's Size =" + list.size());
    }

    @Test
    public void shout02() {
        People xiaoMing = new People("小明", 18);
        Runnable r = () -> {
            //System.out.println(xiaoMing.age);
            // xiaoMing.setAge(20);
            xiaoMing.age = 20;
            System.out.println(xiaoMing.age);
        };
        r.run();
    }

    @Test
    public void shout03() {
        Runnable r = () -> {
            portNumber = 3306;
            System.out.println(portNumber);
        };
        r.run();
    }

    @Test
    public void shout19() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }


    }

    @Test
    public void shout04() {
        int tmp = 1111;
        Runnable r = () -> {
            System.out.println(tmp);
        };
        r.run();
    }

    @Test
    public void shout05() {
        int tmp = 1111;
        Runnable r = () -> {
            System.out.println(tmp);
        };
        r.run();
    }

    @Test
    public void shout99() {
        CompletableFuture<Integer> cf = CompletableFuture.supplyAsync(() -> 1);
        System.out.println(String.format("%s,%.2f ", "interesting", 66.8));

    }

    @Test
    public void shout100() {
        String s = "I am a test String Here!";
        Stream<Character> stream = IntStream.range(0, s.length()).mapToObj(s::charAt);
    }

    @Test
    public void shout06() {
//         使用方法引用实例化对象
        Supplier<People> people = People::new;
        System.out.println(people.get());
        long startTime = System.nanoTime();
        System.out.println("Hello!");
        long endTime = System.nanoTime();
        System.out.println(endTime - startTime);
    }

    @Test
    public void shout07() {
        List<String> words = Arrays.asList("Hello", "Java8", "InAction");
        List<Integer> res = words.stream().map(String::length).collect(toList());
        res.forEach(System.out::println);
    }

    @Test

    public void shout08() {
        List<String> data = Arrays.asList("Hello", "worlllld");
        /*data.stream().map(
                words -> words.split("")).collect(Collectors.toList()).forEach(
                        a -> Arrays.stream(a).distinct().collect(Collectors.toList()).forEach(System.out::print));*/
        List<String[]> res = data.stream().map(words -> words.split("")).collect(toList());
        res.forEach(a -> Arrays.asList(a).forEach(System.out::println));

    }

    @Test
    public void shout09() {
        // Stream 流文件实现
//        List<Stream<String>> res = Stream.of("Hello", "world").map(
//                a -> a.split("")).map(Arrays::stream).distinct().collect(
//                Collectors.toList());
        Stream.of("Hello", "world").map(
                a -> a.split("")).flatMap(Arrays::stream).distinct().collect(
                toList()).forEach(System.out::print);
        /*Converts each element of the Stream into a one dimension array*/
//        int[][] test = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}};
//        Stream.of(test).flatMapToInt(Arrays::stream).distinct().forEach(System.out::print);
        /*Square number*/
        // Stream.of(1, 2, 3, 4, 5).map(a -> a * a).forEach(a -> System.out.print(a + "\t"));


        List<Integer> a = Arrays.asList(1, 2, 3);
        List<Integer> b = Arrays.asList(4, 5);
        // 实现两个列表之间的自由组合
        a.stream().map(i -> i < 4).forEach(System.out::println);
        List<int[]> res = a.stream().flatMap(i -> b.stream().map(j -> new int[]{i, j})).collect(toList());
        // res.forEach(k -> System.out.print(k[0] + " " + k[1] + "\t"));
//        List<int[]> res = a.stream().flatMap(i -> b.stream().map(
//                j -> new int[]{i, j})).filter(k->(k[0]+k[1])%3==0).collect(Collectors.toList());
//         res.forEach(k -> System.out.print(k[0] + " " + k[1] + "\t"));
//        List<int[]> res = a.stream().flatMap(i -> b.stream().filter(j -> (i + j) % 3 == 0).map(
//                j -> new int[]{i, j})).collect(Collectors.toList());
//        res.forEach(k -> System.out.print(k[0] + " " + k[1] + "\t"));
//        res.forEach(a -> a.distinct().forEach(System.out::print));
    }

    @Test
    public void shout10() {
        List<Integer> a = Arrays.asList(1, 2, 3, 88, 76, 55, 66, 88);
        System.out.println(a.stream().reduce(Math::max).get());
    }

    @Test
    public void shout11() {
        List<Integer> a = Arrays.asList(1, 2, 3, 88, 76, 55, 66, 88);
        System.out.println(a.stream().reduce(Integer::sum).get());
    }

    @Test
    public void shout12() {
        List<Integer> a = Arrays.asList(1, 2, 3, 88, 76, 55, 66, 88);
        System.out.println(a.stream().reduce(-379, Integer::sum));
    }

    // Use the Stream to sort the transaction of the one year
    @Test
    public void shout13() {
        List<Integer> transaction = Arrays.asList(1, 2, 3, 88, 76, 55, 66, 88);

//        transaction.sort(Integer::compareTo);
//        for (int i : transaction) {
//            System.out.print(i + "\t");
//        }
    }

    // What are all the unique cities where the traders work?
    @Test
    public void shout14() {
        List<String> cities = Arrays.asList("Beijing", "Shanghai", "Shenzhen", "Guangzhou", "Beijing", "Shanghai", "Shenzhen", "Guangzhou", "Beijing", "Shanghai", "Shenzhen", "Guangzhou");
        cities.stream().distinct().collect(toList()).forEach(a -> System.out.println(a + "\t"));
    }

    @Test
    public void shout15() throws InterruptedException {
        TimeUnit.SECONDS.sleep(1);
        System.out.println("Hello");
    }

    @Test
    public void shout16() {
        ArrayList<Integer> list = new ArrayList<Integer>() {
            {
                add(1);
                add(2);
                add(3);
            }
        };
        System.out.println(list.remove(0));
        System.out.println(list.remove(0));
        System.out.println(list.remove(0));

    }

    @Test
    public void shout28() {
        Function<String, Integer> strToInt = Integer::parseInt;
        System.out.println(transStr("388", strToInt)+11);

    }

    public int transStr(String s,Function<String,Integer> func){
        return func.apply(s);
    }

}

class People {
    String name = "小明";
    int age = 18;

    public People() {
    }

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Test
    public void shout() {

    }


}
